package cn.workreport.modules.group.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.workreport.modules.common.vo.PageVO;
import cn.workreport.modules.group.entity.Group;
import cn.workreport.modules.group.mapper.GroupMapper;
import cn.workreport.modules.group.service.IGroupService;
import cn.workreport.modules.report.dto.UserReportCommitDTO;
import cn.workreport.modules.report.entity.ReportCommit;
import cn.workreport.modules.report.service.impl.ReportCommitServiceImpl;
import cn.workreport.modules.users.entity.UserEntity;
import cn.workreport.modules.users.service.impl.UserServiceImp;
import cn.workreport.modules.users.vo.CommonUserVO;
import cn.workreport.util.JsonResult;
import cn.workreport.util.UserChacheFromToken;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <p>
 * 组织架构表 业务接口实现类
 * </p>
 *
 * @author yyf
 * @since 2022-02-22
 */
@Slf4j
@Service
public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements IGroupService {

    @Autowired
    private UserServiceImp userServiceImp;

    @Autowired
    private ReportCommitServiceImpl reportCommitService;

    @Override
    public void wrapEntity(Group entity) {

    }

    @Override
    public PageVO<Group> pageEntity(IPage<Group> page, Wrapper<Group> queryWrapper) {
        IPage<Group> pageResult = this.page(page, queryWrapper);
        pageResult.getRecords().forEach(entity -> {
            this.wrapEntity(entity);
        });
        return new PageVO<>(pageResult);
    }

    @Override
    public Group getByIdEntity(Integer id) {
        return null;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public JsonResult<?> saveOrUpdateEntity(Group entity) {
        Integer orgId = entity.getOrgId();
        String groupName = entity.getGroupName();
        if (ObjectUtil.isEmpty(orgId)) {
            return JsonResult.fail("参数 orgId 不能为空");
        }
        if (StrUtil.isBlank(groupName)) {
            return JsonResult.fail("参数 groupName 不能为空");
        }

        // 新增：只能有一条没有 parentId （根节点）！
        boolean isCreate = ObjectUtil.isEmpty(entity.getId());
        if (isCreate) {
            if (ObjectUtil.isEmpty(entity.getParentId())) {
                Group rootEntity = getRootEntity(orgId);
                if (!ObjectUtil.isEmpty(rootEntity)) {
                    return JsonResult.fail("已存在根节点，缺少参数 parentId");
                }
            }
        }
        // 编辑：parentId 必传！
        else {
            if (ObjectUtil.isEmpty(entity.getParentId())) {
                Group rootEntity = getRootEntity(orgId);
                if (!ObjectUtil.isEmpty(rootEntity) && !rootEntity.getId().equals(entity.getId())) {
                    return JsonResult.fail("编辑已存在根节点，缺少参数 parentId");
                }
            }
        }

        boolean isSuccess =  super.saveOrUpdate(entity);
        if (!isSuccess) {
            return JsonResult.fail("操作失败");
        }
        return JsonResult.ok();
    }

    @Override
    public JsonResult<?> removeByIdEntity(Integer id) {

        // 找出其下级的所有组织id
        Set<Integer> groupIdSet = new HashSet<>();
        // 把该组织和其下级的所有成员清空重置 groupId isLeader
        boolean isSuccess1 = removeMemberByGroupId(id, groupIdSet);
        if (!isSuccess1) {
            return JsonResult.fail("清空组织成员失败");
        }

        log.info("groupIdSet ===>" + groupIdSet);
        if (ObjectUtil.isNotEmpty(groupIdSet)) {
            boolean isSuccess = this.removeByIds(groupIdSet);
            if (!isSuccess) {
                return JsonResult.fail();
            }
        }
        return JsonResult.ok();
    }

    @Override
    public JsonResult<?> removeByIdsEntity(List<Integer> ids) {
        for (Integer id : ids) {
            JsonResult<?> jsonResult = removeByIdEntity(id);
            if (!jsonResult.getState().equals(JsonResult.SUCCESS)) {
                return JsonResult.fail();
            }
        }
        return JsonResult.ok();
    }

    @Override
    public JsonResult<?> getTreeListAll(Integer orgId) {
        if (ObjectUtil.isEmpty(orgId)) {
            return JsonResult.fail("参数 orgId 不能为空");
        }
        Group rootGroup = getRootEntity(orgId);
        List<Group> rootGroupList = new ArrayList<>();
        if (ObjectUtil.isEmpty(rootGroup)) {
            return JsonResult.ok(rootGroupList);
        }
        List<Group> childrenList = getGroupCascade(rootGroup, 0);
        rootGroup.setChildren(childrenList);
        rootGroupList.add(rootGroup);
        return JsonResult.ok(rootGroupList);
    }

    @Override
    public JsonResult<?> groupReportTree (Date startCreatedTime, Date endCreatedTime, Integer orgId) {
        if (ObjectUtil.isEmpty(orgId)) {
            return JsonResult.fail("参数 orgId 不能为空");
        }
        UserEntity currentLoginUser = UserChacheFromToken.getUser();
        Group userGroup = new Group();
        List<Group> groupList = new ArrayList<>();
        // 如果当前登录用户是超级管理员-则根据 机构id 查出所有
        if (ObjectUtil.isNotEmpty(currentLoginUser.getIsSupperAdmin()) && currentLoginUser.getIsSupperAdmin()) {
            userGroup = getRootEntity(orgId);
            if (ObjectUtil.isNotEmpty(userGroup)) {
                groupList = listGroupReportCascade(userGroup, startCreatedTime, endCreatedTime);
            }
        }
        // 如果当前登录用户是组长，可查看组员和下级
        else if (ObjectUtil.isNotEmpty(currentLoginUser.getIsLeader()) && currentLoginUser.getIsLeader()) {
            // 查出当前登录用户组织
            userGroup = getById(currentLoginUser.getGroupId());
            if (ObjectUtil.isNotEmpty(userGroup)) {
                groupList = listGroupReportCascade(userGroup, startCreatedTime, endCreatedTime);
            }
        }
        // 查询自己组的成员发送的日报记录
        else if (ObjectUtil.isNotEmpty(currentLoginUser.getGroupId())) {
            groupList = this.memberReport(startCreatedTime, endCreatedTime);
        }
        else {
            return JsonResult.fail("当前用户未归组，不可查看组员和下级发送的日报");
        }
        return JsonResult.ok(groupList);
    }

    private List<Group> listGroupReportCascade (Group userGroup, Date startCreatedTime, Date endCreatedTime) {
        List<Group> groupList = new ArrayList<>();
        List<Group> childrenList = getGroupReportCascade(userGroup, 0, startCreatedTime, endCreatedTime);
        userGroup.setChildren(childrenList);
        groupList.add(userGroup);
        return groupList;
    }

    @Override
    public List<Group> memberReport(Date startCreatedTime, Date endCreatedTime) {
        UserEntity currentLoginUser = UserChacheFromToken.getUser();
        // 查出当前登录用户组织
        Group userGroup = getById(currentLoginUser.getGroupId());
        List<Group> groupList = new ArrayList<>();
        if (ObjectUtil.isEmpty(userGroup)) {
            return groupList;
        }
        List<UserEntity> userList = userServiceImp.getUserListByGroupId(userGroup.getId());
        List<UserReportCommitDTO> userReportCommitList = new ArrayList<>();
        for (UserEntity userEntity : userList) {
            UserReportCommitDTO userReportCommitDTO = new UserReportCommitDTO();
            BeanUtil.copyProperties(
                    userEntity,
                    userReportCommitDTO,
                    CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true)
            );
            List<ReportCommit> reportCommitList = reportCommitService.listByUserId(userEntity.getId(), startCreatedTime, endCreatedTime);
            userReportCommitDTO.setReportCommitList(reportCommitList);
            userReportCommitList.add(userReportCommitDTO);
        }
        userGroup.setUserReportCommitList(userReportCommitList);
        userGroup.setLevel(0);
        userGroup.setChildren(new ArrayList<>());
        groupList.add(userGroup);
        return groupList;
    }

    @Override
    public List<Group> listGroupByOrgId(Integer orgId) {
        LambdaQueryWrapper<Group> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Group::getOrgId, orgId);
        wrapper.orderByDesc(Group::getCreatedTime);
        return list(wrapper);
    }

    /**
     * 获取级联数据（获取组织用户发送的日报）
     * @return
     */
    public List<Group> getGroupReportCascade (Group groupEntity, Integer level, Date startCreatedTime, Date endCreatedTime) {
        if (ObjectUtil.isEmpty(groupEntity)) {
            return new ArrayList<>();
        }
        List<Group> childrenList = getGroupChildrenList(groupEntity.getId());
        List<UserEntity> userList = userServiceImp.getUserListByGroupId(groupEntity.getId());
        List<UserReportCommitDTO> userReportCommitList = new ArrayList<>();
        for (UserEntity userEntity : userList) {
            UserReportCommitDTO userReportCommitDTO = new UserReportCommitDTO();
            BeanUtil.copyProperties(
                    userEntity,
                    userReportCommitDTO,
                    CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true)
            );
            List<ReportCommit> reportCommitList = reportCommitService.listByUserId(userEntity.getId(), startCreatedTime, endCreatedTime);
            userReportCommitDTO.setReportCommitList(reportCommitList);
            userReportCommitList.add(userReportCommitDTO);
        }
        groupEntity.setUserReportCommitList(userReportCommitList);
        groupEntity.setLevel(level);
        if (childrenList.size() > 0) {
            for (Group child : childrenList) {
                List<Group> granChildrenList = getGroupReportCascade(child, level + 1, startCreatedTime, endCreatedTime);
                child.setChildren(granChildrenList);
            }
        }
        return childrenList;
    }

    /**
     * 获取级联数据
     * @return
     */
    public List<Group> getGroupCascade (Group groupEntity, Integer level) {
        if (ObjectUtil.isEmpty(groupEntity)) {
            return new ArrayList<>();
        }
        List<Group> childrenList = getGroupChildrenList(groupEntity.getId());
        List<UserEntity> userList = userServiceImp.getUserListByGroupId(groupEntity.getId());
        List<CommonUserVO> newUserList = new ArrayList<>();
        for (UserEntity userEntity : userList) {
            CommonUserVO newUser = new CommonUserVO();
            BeanUtil.copyProperties(
                    userEntity,
                    newUser,
                    CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true)
            );
            newUserList.add(newUser);
        }
        groupEntity.setMembers(newUserList);
        groupEntity.setLevel(level);
        if (childrenList.size() > 0) {
            for (Group child : childrenList) {
                List<Group> granChildrenList = getGroupCascade(child, level + 1);
                child.setChildren(granChildrenList);
            }
        }
        return childrenList;
    }

    /**
     * 获取对应机构的根节点
     * @param orgId 机构id
     * @return Group 实体
     */
    public Group getRootEntity (Integer orgId) {
        LambdaQueryWrapper<Group> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Group::getOrgId, orgId);
        wrapper.isNull(Group::getParentId);
        return this.getOne(wrapper);
    }

    /**
     * 获取子级列表
     * @param parentId
     * @return
     */
    public List<Group> getGroupChildrenList (Integer parentId) {
        List<Group> childrenList = new ArrayList<>();
        if (ObjectUtil.isEmpty(parentId)) {
            return childrenList;
        }
        LambdaQueryWrapper<Group> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Group::getParentId, parentId);
        wrapper.orderByAsc(Group::getOrderNumber);
        childrenList = this.list(wrapper);
        if (ObjectUtil.isNull(childrenList)) {
            return new ArrayList<>();
        }
        return childrenList;
    }

    /**
     * 把所属的成员 groupId 清空 ， 该组织的下级也需要删除
     * @param groupId
     * @return
     */
    private boolean removeMemberByGroupId(Integer groupId, Set<Integer> groupIdSet) {
        groupIdSet.add(groupId);
        // 查询该组织的所有成员列表
        List<UserEntity> userList = userServiceImp.getUserListByGroupId(groupId);
        if (ObjectUtil.isNotEmpty(userList) && userList.size() > 0) {
            // 把所属的成员 groupId isLeader 清空重置
            for (UserEntity userEntity : userList) {
                userEntity.setGroupId(null);
                userEntity.setIsLeader(false);
            }
            // 执行修改成员数据 操作
            boolean isSuccess1 = userServiceImp.updateBatchById(userList);
            if (!isSuccess1) {
                return false;
            }
        }
        // 查询该组织的下级组织列表
        List<Group> childrenList = getGroupChildrenList(groupId);
        if (!ObjectUtil.isEmpty(childrenList) && childrenList.size() > 0) {
            for (Group child : childrenList) {
                // 递归清空下级组织的成员
                boolean isSuccess = removeMemberByGroupId(child.getId(), groupIdSet);
                if (!isSuccess) {
                    return false;
                }
            }
        }
        return true;
    }
}

